package com.smedi.ismedi.inmail.core.port.adapter.service.impl;

import com.smedi.ismedi.inmail.core.domain.aggregatemodel.geo.Location;
import com.smedi.ismedi.inmail.core.port.adapter.service.GeoService;
import com.smedi.ismedi.inmail.core.port.adapter.service.dto.LocationResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@RequiredArgsConstructor
@Service
public class GeoServiceImpl implements GeoService {
    @Value("${geo.url}")
    private String geoUrl;
    @Value("${q.key}")
    private String qKey;

    private final RestTemplateBuilder restTemplateBuilder;

    @Override
    public Location getLocation(String cityName) {
        RestTemplate restTemplate = restTemplateBuilder.build();
        int code = 0;
        List<Location> locations;
        Map<String, String> uriVariables = new HashMap<>();
        uriVariables.put("location", cityName);
        uriVariables.put("key", qKey);

        // 发送请求
        HttpHeaders headers = new HttpHeaders();

        HttpMethod method = HttpMethod.GET;

        HttpEntity<Object> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<LocationResponse> exchange = restTemplate.exchange(geoUrl, method, requestEntity, LocationResponse.class, uriVariables);
        Optional<ResponseEntity<LocationResponse>> response = Optional.of(exchange);

        Optional<Integer> optionalCode = response.map(HttpEntity::getBody).map(LocationResponse::getCode);
        if (!optionalCode.isPresent()) {
            return new Location();
        } else {
            code = optionalCode.get();
        }

        Optional<List<Location>> optionalLocations = response.map(HttpEntity::getBody).map(LocationResponse::getLocation);
        if (!optionalLocations.isPresent()) {
            return new Location();
        } else {
            locations = optionalLocations.get();
        }

        if (code != 200) {
            return new Location();
        }

        if (locations.isEmpty()) {
            return new Location();
        }

        return locations.get(0);
    }
}
